//注释快捷键
//ctrl + / --> 行注释
//ctrl + shift + / --> 块注释



public class Test {
    public static void main1(String[] args) {

        System.out.println("hello world");
        int a = 1;
        System.out.println(a);

        //长整型 8个字节 范围是 -2^63 ~ 2 ^ 63 - 1
        long b = 10L;//长整型一般在常量后面跟一个大写的L表示长整型
        long b_1 = 10L;//也可以跟小写的l，但是不推荐，看起来像101
        System.out.println(b);
        System.out.println(Long.MAX_VALUE);
        System.out.println(Long.MIN_VALUE);
        System.out.println("========================");

        short sh = 10;//短整型 2个字节 范围是 -2 ^ 15 ~ 2 ^ 15 - 1
        System.out.println(Short.MAX_VALUE);
        System.out.println(Short.MIN_VALUE);
        System.out.println("=====================");

        byte b1 = 10;//字节型 1个字节 -2^7 ~ 2^7-1
        System.out.println(Byte.MAX_VALUE);
        System.out.println(Byte.MIN_VALUE);
        System.out.println("=======================");

        double d = 12.5;//双精度浮点型 8个字节
        System.out.println(d);
        System.out.println(Double.MAX_VALUE);
        System.out.println(Double.MIN_VALUE);


    }

    public static void main2(String[] args) {
        int a = 1;
        int b = 2;
        System.out.println(a / b);//运行结果为0
        //从数学上来说是0.5 但是此时在升序上不能保存小数

        //小数在程序上只能是精确到xxxx位
        double num = 1.1;
        System.out.println(num * num);//1.21000000000000000000000002
        System.out.println("====================");
        System.out.println(Double.MAX_VALUE);
        System.out.println(Double.MIN_VALUE);//输出的是浮点数的一个最小的非负整数

        float f = -12.5f;// float f = 12.5F;//大写f也可以
//        float 类型在 Java 中占四个字节, 同样遵守 IEEE 754 标准. 由于表示的数据精度范围较小, 一般在工程上用到浮点数
//        都优先考虑 double, 不太推荐使用 float. float的包装类型为Float。
        System.out.println(f);
    }


    public static void main3(String[] args) {
        char ch = 'A';//char 是占2个字节，这个和C是有区别的
        //一个汉字占两个字节，所以Java的字符类型可以输出更多内容
        System.out.println(ch);
        char ch2 = '赵';
        System.out.println(ch2);
//        char ch3 '找不到';//err
        //char的包装类型为Character
    }

    public static void main4(String[] args) {
        //在c中，0是假，非0是真   但是在Java中 真假 只有 true和false
        boolean flg = true;//没有明确规定占用几个字节！
        System.out.println(flg);
        //不能和任何类型转换
        int a = 20;
//        a = flg;//err
//        a = (int)flg;//err
    }

    public static void main5(String[] args) {
        int a = 10;
        long b = 100L;

        b = a;//隐式类型转换
        System.out.println(b);

//        a = b;//err
        a = (int) b;//强制类型转换，显式类型转换

//        byte c = 256;//err
        byte c = (byte) 256;//right
        byte c2 = 127;
        //Java中，对于字面值的直接赋值是允许的，前提是没有超过该类型的表示范围
        //超过表示范围之后，就会检查

        boolean flg = true;
//        a = (int)flg;//err
        //boolean不能进行类型转换

    }

    public static void main6(String[] args) {
        int a = 10;
        long b = 20;
        //int c = a + b;//等号右边是long类型 左边是int类型
        int c = (int)(a + b);//right
        System.out.println("================");

        //注意：小于4个字节的内容 会 提升为int类型参与运算

        byte b1 = 125;
        byte b2 = 123;
        //byte b3 = (b1 + b2);//err
        byte b3 = (byte)(b1 + b2);
        System.out.println(b3);//-8
        //绕了一圈回来到-8

        int b4 = b1 + b2;
        System.out.println(b4);//248
    }

    public static void main7(String[] args) {
        //在C语言中 有没有字符串这种数据类型？？？
        /*
        char* p = "abcdefg"; //类型是char* 指针
        char[] arr = "abcdefg";//类型是char[] 不是字符串类型
         */
        String str = "hello";//双引号当中，包括若干字符
        System.out.println(str);

        //调用String这个类型的valueOf方法
        int a = 100;
        String s1 = String.valueOf(a);
        System.out.println(s1);

        String s2 = a + "hello";//此时这个加号是拼接的意思
        System.out.println(s2);

        String s3 = 10 + 20 + "x";//30x
        String s4 = "x" + 10 + 20;//x1020
        System.out.println(s3);
        System.out.println(s4);
        System.out.println("==========");

        String str3 = "10009";
        //调用Integer的方法 来实现转换
        int ret = Integer.valueOf(str3);
        System.out.println(ret + 1);

        int ret2 = Integer.parseInt(str3);
        System.out.println(ret2 + 1);

    }

    public static void main8(String[] args) {
        System.out.println(5 / 2);  //2
        System.out.println((float)5 / 2); //2.5
        System.out.println(5 / (float)2); //2.5
        System.out.println((float)(5 / 2));//2.0
        System.out.println("==============");
        System.out.println(10 % 3);//1
        System.out.println(10 % -3);//1
        System.out.println(-10 % 3);//-1
        System.out.println(-10 % -3);//-1
        System.out.println("================");
        System.out.println(11.5 % 2);//1.5
    }

    public static void main9(String[] args) {
        //增量运算符
        int a = 1;
        a += 2; // a = a + 2
        System.out.println(a); // 此时a = 3

        a -= 1;// a = a - 1; --> a = 3 - 1 =2
        System.out.println(a);

        a *= 3;//a = a * 3; --> a = 2 * 3 = 6
        System.out.println(a);

        a /= 3; //a = a / 3 --> a = 6 / 3
        System.out.println(a);//2

        a %= 2;// a =  a % 2 --> a = 2 % 2
        System.out.println(a);//0

        long d = 100L;
        int c = 9;
        //c = c + d;//err ,等号右边会提升成为long类型,左边是int类型，不匹配
        c +=d;//right ==> c = (int)(c + d);
        System.out.println(c);//right
        //特点:增量运算符会帮我们进行类型转换
        System.out.println("==================");

        //自增/自减运算符 ++ --
        //++a :前置加加，是先++再使用
        //--a :后置加加，是先使用后++
        int a1 = 10;
        System.out.println((a1++));//10
        System.out.println(a1);//11
        //注意自增或者自减运算符是有副作用的运算符，会改变变量的值
    }

    public static void main10(String[] args) {
        //关系运算符 == != < > <= >=
        //Java中只有true 和 false 没有 0 和 1
        int a = 10;
        int b = 20;
        System.out.println(a == b);//false
        System.out.println(a != b);//true
        System.out.println(a > b);//false
        System.out.println(a < b);//true
        System.out.println(a >= b);//false
        System.out.println(a <= b);//true

        //注意：强调，Java和C不一样的地方在于，需要多次判断的时候，不能连着写
        //比如 3 < a < 20 //err
        //int flg = (3 < a < 20);//err
        // boolean fla = (3 < a < 20);//err
        //因为 3 < a 判断之后 结果是false / true 没办法再和20进行运算
    }

    public static void main11(String[] args) {
        //逻辑运算符
        // && || ！ 运算结果都是boolean类型
        //1.&&逻辑与
        //注意逻辑运算符表达式必须都是boolean类型
        int a = 10;
        int b = 20;
        System.out.println(a == b && a > b);
        //230行的代码使用了逻辑运算符&&
        //补充：&&运算符，表达式1如果判断为false的话，表达式2是不会执行的
        System.out.println((a == b) && (a % 0 == 20));//no err
        System.out.println((a == b) & (a % 0 == 20));//err,这样就无法表示短路


    }

    public static void main12(String[] args) {
        int a = 10;
        int b = 20;
        int c = (a > b) ? a : b;
        System.out.println(c);
    }

    public static void main13(String[] args) {
        //位(按照二进制位进行运算)运算符 & | ~ ^
        //按位与&
        int a = 10;//0000 1010
        int b = 20;//0001 0100
        //a & b 如果两个二进制都是1则为1 否则为0
        //           0000 0000
        System.out.println(a & b);//0

        System.out.println("====================");

        //按位取反
        int a1 = 0xf;
        System.out.printf("%x\n", ~a1);
        //System.out.printf 能够格式化输出内容
        //0xf
        //00000000 00000000 00000000 00001111 - 0xf
        //原反补都相同
        //~a
        //11111111 11111111 11111111 11110000
        //正数原反补都相同
        //十六进制
        //FFFFFFF0


        //按位异或
        //^ :表示，如果两个数字的二进制位，如果相同则为0，相异则为1
        int t = 0x1;
        int m = 0x2;
        //0000 0001
        //0000 0010
        //^            相同为0 相异为1
        //0000 0011 --> 3

        System.out.printf("%x\n", t ^ m);//3
    }

    public static void main14(String[] args) {
        //移位运算符： << >> >>>
        //1.左移 << ：最左侧位丢掉，最右侧补0
        int a = 10;
        System.out.printf("%d\n", a << 1); // 20
        //0000 1010
        //  <<
        //0001 0100 - 20
        int t = a << 1;
        System.out.printf("%d\n", t << 1);
        //10 << 1 --> 10*2^1
        //10 << 2 --> 10*2^2
        //向左移的时候，丢弃的是符号位，因此正数左移可能会出现负数
        System.out.println("================");

        int b  = 10;
        System.out.printf("%d\n", b >> 1);
        //0000 1010
        //>>
        //0000 0101 5
        int m = b >> 1;
        System.out.printf("%d\n", m >> 1);
        //右移的时候，最右侧位不要了，最左侧符号位(正数补0，负数补1)

        //无符号右移 >>>
        int p = -10;
        //-10
        //10000000 00000000 00000000 00001010
        //11111111 11111111 11111111 11110101
        //11111111 11111111 11111111 11110110 - 补码
        //>>>
        //01111111 11111111 11111111 11111011
        //>>
        //11111111 11111111 11111111 11111011 - 补码
        //10000000 00000000 00000000 00000100
        //10000000 00000000 00000000 00000101 - 原码 //-5
        System.out.println(p>>1);
        System.out.println(p>>>1);

        /**
         * 总结：
         * 1.左移N位：相当于原数字 * 2 的 N 次方
         * 2.右移N位：相当于原数字 / 2 的 N 次方
         * 3.由于计算机计算移位效率高于计算乘除，当某个代码正好乘除2的N次方的时候，可以用移位运算代替
         * 4.移动负数或者移动位数过大都没有意义
         */
    }

    public static void main(String[] args) {
        //条件运算符
        // 表达式1 ？ 表达式2 : 表达式三
        //三目操作符
        int a = 10;
        int b = 20;
        int c = (a > b) ? a : b;
        System.out.println(c);
        //注意：
        //1.表达式2和表达式3要是同类型的，除非是能发生隐式转换的
        double d =  a > b ? 2.0 : 1;
        System.out.println(d);
        //2.表达式不能单独存在，其产生的结果必须要被使用
//        a > b ? a :b;//err
    }
    //运算符的优先级，加括号即可
}


